package com.gitee.wsl.compose.use.coroutines

//package xyz.junerver.compose.hooks

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import com.gitee.wsl.compose.state.S
import com.gitee.wsl.compose.state.S.state
import com.gitee.wsl.compose.state.ext.useLatestState
import com.gitee.wsl.coroutines.strategy.Throttle
import com.gitee.wsl.coroutines.strategy.ThrottleOptions
import com.gitee.wsl.ext.reflect.VoidFunction
import com.gitee.wsl.ext.reflect.invoke

@Composable
fun <S> useThrottle(value: S, options: ThrottleOptions = ThrottleOptions.instance): S {
    val (throttled, setThrottled) = state(value)
    val throttledSet = useThrottleFn(fn = {
        setThrottled(value)
    }, options)
    LaunchedEffect(key1 = value, block = {
        throttledSet()
    })
    return throttled
}

@Composable
fun useThrottleFn(
    fn: VoidFunction,
    options: ThrottleOptions = ThrottleOptions.instance,
): VoidFunction {
    val latestFn by S.useLatestState(fn)
    val scope = rememberCoroutineScope()
    val throttled = remember {
        Throttle(scope, options, latestFn)
    }.apply { this.fn = latestFn }
    return throttled
}


@Composable
fun useThrottleEffect(
    vararg keys: Any?,
    options: ThrottleOptions = ThrottleOptions.instance,
    block: () -> Unit,
) {
    val throttledBlock = useThrottleFn(fn = { block() }, options)
    LaunchedEffect(*keys) {
        throttledBlock.invoke()
    }
}
